package com.framework.loippi.utils.qiniu;


import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;


@Service("fileServiceImpl4Qiniu")
public class FileServiceImpl4Qiniu implements FileService4Qiniu {

    private Logger log = Logger.getLogger(getClass());
    public static final String uploadImageExtension = "jpg,jpeg,bmp,gif,png";
    public static final String uploadFlashExtension = "swf,flv";
    public static final String uploadMediaExtension = "swf,flv,mp3,wav,mp4,avi,rm,rmvb";
    public static final String uploadFileExtension = "zip,rar,7z,doc,docx,xls,xlsx,ppt,pptx";
    /**
     * 分隔符
     */
    private static final String SEPARATOR = ",";

    /**
     * 文件类型
     */
    public enum FileType {

        /**
         * 图片
         */
        image,

        /**
         * Flash
         */
        flash,

        /**
         * 媒体
         */
        media,

        /**
         * 文件
         */
        file
    }


    @Resource
    private TaskExecutor taskExecutor;

    @Value("${qiniu.region}")
    private String region;
    @Value("${qiniu.accessKey}")
    private String accessKey;
    @Value("${qiniu.secretKey}")
    private String secretKey;
    @Value("${qiniu.url}")
    private String domainUrl;
    @Value("${qiniu.bucket}")
    private String bucket;

    @Override
    public boolean isValid(FileType fileType, MultipartFile multipartFile) {
        if (multipartFile == null) {
            return false;
        }
        String[] uploadExtensions;
        if (fileType == FileType.flash) {
            uploadExtensions = getUploadFlashExtensions();
        } else if (fileType == FileType.media) {
            uploadExtensions = getUploadMediaExtensions();
        } else if (fileType == FileType.file) {
            uploadExtensions = getUploadFileExtensions();
        } else {
            uploadExtensions = getUploadImageExtensions();
        }
        if (ArrayUtils.isNotEmpty(uploadExtensions)) {
            return FilenameUtils.isExtension(multipartFile.getOriginalFilename(), uploadExtensions);
        }
        return false;
    }

    @Override
    public String upload(MultipartFile multipartFile, boolean async) {
        try {
            Configuration config = new Configuration();
            UploadManager uploadManager = new UploadManager(config);
            Auth auth = Auth.create(accessKey, secretKey);

            String filename = UUID.randomUUID().toString().concat("." + FilenameUtils.getExtension(multipartFile.getOriginalFilename()));
            if (async) {
                addTask(multipartFile, filename);
            } else {
                uploadManager.put(multipartFile.getBytes(), filename, auth.uploadToken(bucket));

            }
            return domainUrl.concat(filename);
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时简单状态信息
            log.error(r.toString());
            try {
                // 响应的文本信息
                log.error(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public String upload(File file, boolean async) {
        try {
            Configuration config = new Configuration();
            UploadManager uploadManager = new UploadManager(config);
            Auth auth = Auth.create(accessKey, secretKey);

            String filename = UUID.randomUUID().toString() + ".jpg";
            uploadManager.put(file, filename, auth.uploadToken(bucket));
            return domainUrl.concat(filename);
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时简单状态信息
            log.error(r.toString());
            try {
                // 响应的文本信息
                log.error(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String upload(File file) {
        try {
            Configuration config = new Configuration();
            UploadManager uploadManager = new UploadManager(config);
            Auth auth = Auth.create(accessKey, secretKey);

            String filename = UUID.randomUUID().toString() + ".amr";
            uploadManager.put(file, filename, auth.uploadToken(bucket));
            return domainUrl.concat(filename);
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时简单状态信息
            log.error(r.toString());
            try {
                // 响应的文本信息
                log.error(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 添加上传任务
     */
    private void addTask(final MultipartFile multipartFile, final String filename) {
        taskExecutor.execute(new Runnable() {
            public void run() {
                try {
                    Configuration config = new Configuration();
                    UploadManager uploadManager = new UploadManager(config);
                    Auth auth = Auth.create(accessKey, secretKey);

                    uploadManager.put(multipartFile.getBytes(), filename, auth.uploadToken(bucket));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


    /**
     * 获取允许上传图片扩展名
     *
     * @return 允许上传图片扩展名
     */
    public String[] getUploadImageExtensions() {
        return StringUtils.split(uploadImageExtension, SEPARATOR);
    }

    /**
     * 获取允许上传Flash扩展名
     *
     * @return 允许上传Flash扩展名
     */
    public String[] getUploadFlashExtensions() {
        return StringUtils.split(uploadFlashExtension, SEPARATOR);
    }

    /**
     * 获取允许上传媒体扩展名
     *
     * @return 允许上传媒体扩展名
     */
    public String[] getUploadMediaExtensions() {
        return StringUtils.split(uploadMediaExtension, SEPARATOR);
    }

    /**
     * 获取允许上传文件扩展名
     *
     * @return 允许上传文件扩展名
     */
    public String[] getUploadFileExtensions() {
        return StringUtils.split(uploadFileExtension, SEPARATOR);
    }

    public String getToken() {
        Auth auth = Auth.create(accessKey, secretKey);
        String token = auth.uploadToken(bucket);
        return token;
    }


    /**
     * 下载文件到本地
     *
     * @param urlString 被下载的文件地址
     * @param filename  本地文件名
     * @throws Exception 各种异常
     */
    public void download(String urlString, String filename) throws Exception {
        // 构造URL
        URL url = new URL(urlString);
        // 打开连接
        URLConnection con = url.openConnection();
        // 输入流
        InputStream is = con.getInputStream();
        // 1K的数据缓冲
        byte[] bs = new byte[1024];
        // 读取到的数据长度
        int len;
        // 输出的文件流
        OutputStream os = new FileOutputStream(filename);
        // 开始读取
        while ((len = is.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
        // 完毕，关闭所有链接
        os.close();
        is.close();
    }


    /**
     * 删除文件
     *
     * @param filename
     */
    public void delFile(String filename) {

        Auth auth = Auth.create(accessKey, secretKey);
        //构造一个带指定Zone对象的配置类
        Configuration config = new Configuration(Zone.zone2());
//		  华东	Zone.zone0()
//		  华北	Zone.zone1()
//		  华南	Zone.zone2()
//		  北美	Zone.zoneNa0()
//		  东南亚	Zone.zoneAs0()
        BucketManager bucketManager = new BucketManager(auth, config);
        try {
            bucketManager.delete(bucket, filename);
        } catch (QiniuException ex) {
            //如果遇到异常，说明删除失败
            System.err.println(ex.code());
            System.err.println(ex.response.toString());
        }

    }

    public static void main(String[] args) throws Exception {

        try {


//		UploadManager uploadManager = new UploadManager();
//	    Auth auth = Auth.create(QINIU_AK, QINIU_SK);
//		File file =new File("D://test.amr");
//		 String filename = UUID.randomUUID().toString()+".amr";
//		uploadManager.put(file, filename , auth.uploadToken(QINIU_TOKEN));
//	   System.out.println(QINIU_PREFIX.concat(filename)); 


        } catch (Exception e) {

        }
    }

}
